package com.demo.java.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;

// -Xmx10m -Xms10m
// 1. 强引用，内存不够时OOM也不会回收
// 2. 软引用, 内存不足时OOM之前会回收软引用的对象判断内存是否够用，不够的话再OOM。使用场景: 缓存，缓存中有数据就从缓存中取，没有就从数据库取。
// 3. 弱引用, 垃圾回收时直接回收弱引用的对象。引用场景: ThreadLocal使用弱引用防止内存泄漏
// 4. 虚引用, 配合ReferenceQueue使用，只能通过queue来获取虚引用的对象，垃圾回收时会将对象放在queue中，
//    只有queue中的元素和对应的虚引用对象置为null时，才会被回收。
//    使用场景: 堆外内存的管理.
public class PhantomReferenceTest {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();
        PhantomReference<byte[]> phantomReference = new PhantomReference<byte[]>(new byte[1024 * 1024 * 5], queue);

        System.out.println(queue.poll());

        System.gc();

        Thread.sleep(100);

        Reference<? extends byte[]> poll = queue.poll();
        System.out.println(poll);

        // 垃圾回收时会将虚引用对象放入queue，只有当虚引用指针和queue中对象指针都置为null才会被回收
        phantomReference = null;
        poll = null;

        System.out.println(poll);

        byte[] bytes = new byte[1024 * 1024 * 6];

    }
}
